/**
 * 统一的消息通信系统
 * 提供类型安全的消息发送和接收功能
 */

/**
 * 消息发送器 - 用于发送消息并等待响应
 */
export class MessageSender {
  /**
   * 发送消息到 background script
   */
  static async sendToBackground<T extends BaseMessage, R extends BaseResponse>(message: T): Promise<R> {
    try {
      const response = await browser.runtime.sendMessage({
        ...message,
        timestamp: Date.now(),
        requestId: this.generateRequestId(),
      });

      if (response?.error) {
        throw new Error(response.error);
      }

      return response;
    } catch (error) {
      console.error("Failed to send message to background:", error);
      throw error;
    }
  }

  /**
   * 发送消息到 content script
   */
  static async sendToContent<T extends BaseMessage, R extends BaseResponse>(tabId: number, message: T): Promise<R> {
    try {
      const response = await browser.tabs.sendMessage(tabId, {
        ...message,
        timestamp: Date.now(),
        requestId: this.generateRequestId(),
      });

      if (response?.error) {
        throw new Error(response.error);
      }

      return response;
    } catch (error) {
      console.debug("Failed to send message to content script:", error);
      throw error;
    }
  }

  /**
   * 发送消息到所有标签页的 content script
   */
  static async broadcastToContent<T extends BaseMessage>(message: T): Promise<void> {
    try {
      const tabs = await browser.tabs.query({});
      const promises = tabs.map((tab) => {
        if (tab.id) {
          return this.sendToContent(tab.id, message).catch((err) => {
            // 忽略无法发送的标签页（如 chrome:// 页面）
            console.debug(`Failed to send to tab ${tab.id}:`, err);
          });
        }
      });

      await Promise.allSettled(promises);
    } catch (error) {
      console.error("Failed to broadcast to content scripts:", error);
      throw error;
    }
  }

  /**
   * 生成唯一的请求ID
   */
  private static generateRequestId(): string {
    return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  }
}

/**
 * 消息路由器 - 用于处理接收到的消息
 */
export class MessageRouter {
  /** 消息处理器映射表 */
  private handlers = new Map<MessageType, MessageHandler>();
  /** 中间件数组 */
  private middlewares: ((message: BaseMessage, sender: Browser.runtime.MessageSender) => boolean | Promise<boolean>)[] =
    [];

  /**
   * 注册消息处理器
   */
  register<T extends BaseMessage, R extends BaseResponse>(type: MessageType, handler: MessageHandler<T, R>): void {
    this.handlers.set(type, handler as unknown as MessageHandler);
  }

  /**
   * 批量注册消息处理器
   */
  registerBatch(handlers: Record<MessageType, MessageHandler>): void {
    Object.entries(handlers).forEach(([type, handler]) => {
      this.register(type as MessageType, handler);
    });
  }

  /**
   * 添加中间件
   */
  use(middleware: (message: BaseMessage, sender: Browser.runtime.MessageSender) => boolean | Promise<boolean>): void {
    this.middlewares.push(middleware);
  }

  /**
   * 处理消息
   */
  async handle(message: BaseMessage, sender: Browser.runtime.MessageSender): Promise<BaseResponse> {
    try {
      // 执行中间件
      for (const middleware of this.middlewares) {
        const shouldContinue = await middleware(message, sender);
        if (!shouldContinue) {
          return {
            success: false,
            error: "Request blocked by middleware",
            timestamp: Date.now(),
          };
        }
      }

      const handler = this.handlers.get(message.type);
      if (!handler) {
        return {
          success: false,
          error: `No handler found for message type: ${message.type}`,
          timestamp: Date.now(),
        };
      }

      const result = await handler(message, sender);
      return {
        ...result,
        success: result.success !== false,
        timestamp: Date.now(),
      };
    } catch (error) {
      console.error(`Error handling message ${message.type}:`, error);
      return {
        success: false,
        error: error instanceof Error ? error.message : "Unknown error",
        timestamp: Date.now(),
      };
    }
  }

  /**
   * 启动消息监听
   */
  startListening(): void {
    browser.runtime.onMessage.addListener(
      (message: BaseMessage, sender: Browser.runtime.MessageSender, sendResponse) => {
        this.handle(message, sender)
          .then((response) => sendResponse(response))
          .catch((error) => {
            console.error("Message handling error:", error);
            sendResponse({
              success: false,
              error: error.message || "Internal error",
              timestamp: Date.now(),
            });
          });

        return true; // 保持消息通道打开
      }
    );
  }
}

/**
 * 消息验证中间件
 */
export const validateMessageMiddleware = (message: BaseMessage, sender: Browser.runtime.MessageSender): boolean => {
  // 验证消息结构
  if (!message || !message.type) {
    console.warn("Invalid message structure:", message);
    return false;
  }

  // 验证消息类型
  if (!Object.values(MessageType).includes(message.type)) {
    console.warn("Unknown message type:", message.type);
    return false;
  }

  return true;
};

/**
 * 日志中间件
 */
export const loggingMiddleware = (message: BaseMessage, sender: Browser.runtime.MessageSender): boolean => {
  if (LOGGER_CONFIG.enabled) {
    console.log(`${LOGGER_CONFIG.prefix} Received message:`, {
      type: message.type,
      sender: sender.tab?.url || sender.url || "unknown",
      timestamp: new Date().toISOString(),
    });
  }
  return true;
};

/**
 * 快速创建消息发送函数
 */
export const createMessageSender = <T extends BaseMessage, R extends BaseResponse>(type: MessageType) => {
  return (data: Omit<T, "type">): Promise<R> => {
    return MessageSender.sendToBackground({
      type,
      ...data,
    } as T);
  };
};
